package it.unica.informatica.enotes.manager;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;

import it.unica.informatica.enotes.notes.Note;
import it.unica.informatica.enotes.notes.AttachmentItem;

/**
 * This class perform all the translations between a note object and its json decode
 * @author Mirko Marras
 * @version 1.0
 */
public class JsonManager {

    private static final String KEY_TEXT_CONTENT = "text_content";
    private static final String KEY_ATTACH_ITEMS = "attach_item";
    private static final String KEY_ATTACH_NAME = "attach_name";
    private static final String KEY_ATTACH_TYPE = "attach_type";
    private static final String KEY_ATTACH_CONTENT = "attach_content";
    private static final String KEY_ATTACH_THUMBNAILS = "attach_thumbnails";

    /**
     * Get the ASCII string that contains the text content of the note based on the JSON string
     * @param extraData The JSON string that encapsulates the content of a note
     * @return The ASCII string that contains the text content of the note based on the JSON string
     */
    public static String getNoteContent(String extraData) {
        try {
            /* Create a JSONObject from the string parameter */
            JSONObject jsonNoteContent = (JSONObject) new JSONParser().parse(extraData);

            /* If the JSONObject is correctly created, return the note text content contained in the JSON */
            if(jsonNoteContent != null) {
                return (String) jsonNoteContent.get(KEY_TEXT_CONTENT);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return "";
    }

    /**
     * Get the list of all the attachments of the note based on the JSON string
     * @param extraData The JSON string that encapsulates the content of a note
     * @return The list of all the attachments of the note based on the JSON string
     */
    public static ArrayList<AttachmentItem> getNoteAttachments(String extraData) {
        /* This ArrayList will store all the retrieved note attachments */
        ArrayList<AttachmentItem> attachments = new ArrayList<AttachmentItem>();

        JSONObject jsonNoteContent = null;
        try {
            /* Create a JSONObject from the string parameter */
            jsonNoteContent = (JSONObject) new JSONParser().parse(extraData);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        /* If the JSONObject is correctly created, encode each attachment from the JSON */
        if(jsonNoteContent != null) {

            JSONArray jsonAttachments = (JSONArray) jsonNoteContent.get(KEY_ATTACH_ITEMS);

            /* For each attachment, translate set the current attachment properties with the translated JSON value */
            for (int i = 0; i < jsonAttachments.size(); i++) {
                JSONObject jsonAttach = (JSONObject) jsonAttachments.get(i);

                /* Set the standard properties */
                AttachmentItem attach = new AttachmentItem();
                attach.setName((String) jsonAttach.get(KEY_ATTACH_NAME));
                attach.setType((String) jsonAttach.get(KEY_ATTACH_TYPE));
                attach.setContent((String) jsonAttach.get(KEY_ATTACH_CONTENT));

                /* Decode and set the thumbnails of the attachment */
                byte[] decodedByte = Base64.decode((String) jsonAttach.get(KEY_ATTACH_THUMBNAILS), 0);
                attach.setThumbnails(BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length));

                /* Add the attachment to the result */
                attachments.add(attach);
            }
        }

        return attachments;
    }

    /**
     * Translates the text content and all the attachments of the note in a JSON string
     * @param note The note to translate in JSON
     * @return The JSON string that encapsulates the text content and the attachment of the note
     */
    public static String toJSON(Note note) {
        /* This JSONObject will store the JSON encode of the note */
        JSONObject jsonNoteContent = new JSONObject();

        /* Add the note text content to the JSON */
        jsonNoteContent.put(KEY_TEXT_CONTENT, note.getContent());

        /* For each note attachment, add it to the JSON */
        JSONArray jsonAttachments = new JSONArray();
        for (AttachmentItem attach : note.getAttachments()) {
            JSONObject jsonAttach = new JSONObject();

            /* Decode the standard properties */
            jsonAttach.put(KEY_ATTACH_NAME, attach.getName());
            jsonAttach.put(KEY_ATTACH_TYPE, attach.getType());
            jsonAttach.put(KEY_ATTACH_CONTENT, attach.getContent());

            /* Encode the attachment thumbnails */
            Bitmap bm = attach.getThumbnails();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
            byte[] byteArrayImage = baos.toByteArray();
            jsonAttach.put(KEY_ATTACH_THUMBNAILS, Base64.encodeToString(byteArrayImage, Base64.DEFAULT));

            /* Add the attachment to the list */
            jsonAttachments.add(jsonAttach);
        }

        /* Add all the JSON attachments to the result */
        jsonNoteContent.put(KEY_ATTACH_ITEMS, jsonAttachments);

        return jsonNoteContent.toJSONString();
    }
}